package com.example.bluetooth;

import androidx.appcompat.app.AppCompatActivity;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private String TAG = "xieyun";
    private Button btn_Open, btn_Close, btn_Discover, btn_Search, btn_Paired, btn_Pair, btn_UnPair, btn_Server, btn_ServerUnconnect, btn_Connect, btn_UnConnect, btn_ClientRev, btn_ClientSend, btn_ServerRev, btn_ServerSend;
    //请求能够打开蓝牙
    private static final int REQUEST_ENABLE = 0x01;
    //请求权限
    private static final int REQUEST_CODE_PERMISSION_LOCATION = 0x02;
    private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
    //本地蓝牙
    private BluetoothAdapter mBluetoothAdapter;
    //蓝牙配对客户端的socket
    private BluetoothSocket bluetoothSocket;
    //远程蓝牙
    private BluetoothDevice bluetoothDevice;
    //服务器端的socket
    private BluetoothServerSocket serverSocket;
    //服务器接收的客户端socket
    private BluetoothSocket serverClentSocket;

    private AcceptThread acceptThread; //服务端线程
    private ClientThread clientThread; //客户端线程

    private OutputStream outputStream; //输出流
    private InputStream inputStream; //输入流
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();//初始化事件

        checkBLEFeatrue();//检测蓝牙
//        checkPermissions();//检测权限
    }

    private void initView() {
        //先要获取默认的蓝牙适配器
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();


        //当蓝牙状态发生变化时，要修改注册信息
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND); //寻找蓝牙
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); //蓝牙搜索结束
        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//蓝牙设备状态改变
        registerReceiver(mReceive, filter);

        //绑定控件
        btn_Open = findViewById(R.id.bt_op_id);
        btn_Close = findViewById(R.id.bt_close_id);
        btn_Discover = findViewById(R.id.bt_discovered_id);
        btn_Search = findViewById(R.id.bt_search_id);
        btn_Pair = findViewById(R.id.bt_Pair_id);
        btn_Paired = findViewById(R.id.bt_paired_id);
        btn_UnPair = findViewById(R.id.bt_unPair_id);
        btn_Server = findViewById(R.id.bt_server_id);
        btn_ServerUnconnect = findViewById(R.id.bt_serverUnconnect_id);
        btn_Connect = findViewById(R.id.bt_connect_id);
        btn_UnConnect = findViewById(R.id.bt_unConnect_id);
        btn_ClientRev = findViewById(R.id.bt_clientRev_id);
        btn_ClientSend = findViewById(R.id.bt_clientSend_id);
        btn_ServerRev = findViewById(R.id.bt_ServerRev_id);
        btn_ServerSend = findViewById(R.id.bt_ServerSend_id);

        btn_Open.setOnClickListener(this);
        btn_Close.setOnClickListener(this);
        btn_Discover.setOnClickListener(this);
        btn_Search.setOnClickListener(this);
        btn_Pair.setOnClickListener(this);
        btn_Paired.setOnClickListener(this);
        btn_UnPair.setOnClickListener(this);
        btn_Server.setOnClickListener(this);
        btn_ServerUnconnect.setOnClickListener(this);
        btn_Connect.setOnClickListener(this);
        btn_UnConnect.setOnClickListener(this);
        btn_ClientRev.setOnClickListener(this);
        btn_ClientSend.setOnClickListener(this);
        btn_ServerRev.setOnClickListener(this);
        btn_ServerSend.setOnClickListener(this);
    }
    private void checkBLEFeatrue() {
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Log.i(TAG, "设备不支持BLE");
            return;
        } else {
            Log.i(TAG, "设备支持蓝牙");
        }
    }
    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.bt_op_id:
                enableBluetooth();//打开蓝牙
                break;
            case R.id.bt_close_id:
                claseBluetooh();//关闭蓝牙
                break;
            case R.id.bt_discovered_id:
                disCovereEnable();//允许被搜索
                break;
            case R.id.bt_paired_id:
                pairedConnect();//已经配对的设备

                break;
            case R.id.bt_Pair_id: //蓝牙配对
                paireDevice();
                break;
            case R.id.bt_search_id:
                mBluetoothAdapter.startDiscovery();//搜索设备
                Log.i(TAG,"开始进行搜索");
                break;
            case R.id.bt_unPair_id:
                unPairDevice();  //取消蓝牙配对
                break;
            case R.id.bt_server_id:
                serverOpen(); //打开服务器
                break;
            case R.id.bt_serverUnconnect_id:
                serverUnconnect(); //服务器断开连接
                break;
            case R.id.bt_connect_id:
                clientConnectDevices();//客户端蓝牙连接
                break;
            case R.id.bt_unConnect_id:
                clientUnConnectDevices(); //客户端取消蓝牙连接
                break;
            case R.id.bt_clientRev_id:
                clentReadRev();//客户端接收数据
                break;
            case R.id.bt_clientSend_id:
                clientSendData(); //客户端发送数据
                break;
            case R.id.bt_ServerRev_id:
                serverReadRev();  //服务器接收数据
                break;
            case R.id.bt_ServerSend_id:
                serverSendData(); //服务器发生数据
                break;
            default:
                break;
        }

    }

    //打开蓝牙
    private void enableBluetooth() {
        if (mBluetoothAdapter == null) {
            Log.i(TAG, "设备不支持蓝牙功能");
            return;
        }
        //如果蓝牙没有打开，我们就要将蓝牙打开
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, REQUEST_ENABLE);

        } else {
            Log.i(TAG, "蓝牙已经打开");
        }
    }
    //关闭蓝牙
    private void claseBluetooh() {
        if (mBluetoothAdapter.isEnabled()) {
            mBluetoothAdapter.disable();
            Log.i(TAG, "关闭蓝牙");
        }
    }
    private void disCovereEnable() {

        if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
            Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
            startActivity(discoverableIntent);
            Log.i(TAG, "已设置蓝牙为搜索状态");
        } else {
            Log.i(TAG, "蓝牙模式是：" + mBluetoothAdapter.getScanMode());
        }
    }

    //匹配蓝牙
    private void paireDevice() {
        if (mBluetoothAdapter.isDiscovering()) {
            mBluetoothAdapter.cancelDiscovery();
        }
        try {
            Method method = bluetoothDevice.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
            try {
                method.invoke(bluetoothDevice, 1);
                Log.i(TAG, "匹配成功");
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                Log.i(TAG, "匹配失败");
            } catch (InvocationTargetException e) {
                e.printStackTrace();
                Log.i(TAG, "匹配失败");
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            Log.i(TAG, "匹配失败");
        }
    }

    //已经匹配好的蓝牙
    private void pairedConnect() {
        //设置列表
        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
        if (pairedDevices.size() > 0) {
            //遍历列表，打印蓝牙名字跟蓝牙地址
            for (BluetoothDevice device : pairedDevices) {
                Log.i(TAG, "device name" + device.getName() + "device address" + device.getAddress());
            }
        } else {
            Log.i(TAG, "没有找到匹配的蓝牙");
        }
    }

    //取消蓝牙匹配
    private void unPairDevice() {
        Method method = null;
        //配对之前把扫描关闭
        if (mBluetoothAdapter.isDiscovering()) {
            mBluetoothAdapter.cancelDiscovery();
        }
        try {
            //移除设备把类文件设置为空值
            method = bluetoothDevice.getClass().getMethod("removeBond", (Class[]) null);
            method.invoke(bluetoothDevice,(Objects[])null);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        try {
            method.invoke(bluetoothDevice, (Objects[]) null);
            Log.i(TAG, "取消蓝牙配对");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    //打开服务
    private void serverOpen(){
        acceptThread = new AcceptThread();
        acceptThread.start();
    }
    //服务器断开连接
    private void serverUnconnect(){
        acceptThread.cancel();
    }
    //客户端蓝牙连接
    private void clientConnectDevices(){
        clientThread=new ClientThread();
        clientThread.start();
    }
    //客户端断开蓝牙连接
    private void clientUnConnectDevices(){
        clientThread.cancel();
    }

    //开启服务器端的线程，用来监听和接收客户端的请求
    private class AcceptThread extends Thread{
        public AcceptThread() {
            BluetoothServerSocket temp = null;
            try {
                temp=mBluetoothAdapter.listenUsingRfcommWithServiceRecord("BLUE_TEST",MY_UUID);

            } catch (IOException e) {
                e.printStackTrace();
            }
            serverSocket=temp;
            Log.i(TAG,"服务器端已经创建成功");
        }

        @Override
        public void run() {
            while (true){
                try {
                    BluetoothSocket socket = serverSocket.accept();//阻塞
                    if (socket!=null){
                        serverClentSocket=socket;
                        Log.d(TAG,"服务器端连接成功");

                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.e(TAG,"连接失败！");
                }
            }
        }
        private void cancel(){
            if (serverSocket!=null){
                try {
                    serverSocket.close();
                    serverSocket=null;
                    Log.i(TAG,"服务器端取消连接");
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }
    //开启客户端的线程，用来监听和接收服务器的请求
    private class ClientThread extends Thread{
        public ClientThread(){
            BluetoothSocket temp = null;
            if (mBluetoothAdapter.isDiscovering()){
                mBluetoothAdapter.cancelDiscovery();
            }
            try {
                bluetoothDevice.createInsecureRfcommSocketToServiceRecord(MY_UUID);
            } catch (IOException e) {
                e.printStackTrace();
            }
            bluetoothSocket=temp;

        }

        @Override
        public void run() {
            try {
                bluetoothSocket.connect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        private void cancel(){
            if (bluetoothSocket!=null&&bluetoothSocket.isConnected()){
                try {
                    bluetoothSocket.close();
                    bluetoothSocket=null;
                    Log.i(TAG,"取消设备连接");
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }

    }

    //客户端接收数据
    public void clentReadRev(){
        ReadReceiveThread clientReadThread = new ReadReceiveThread(bluetoothSocket);
        clientReadThread.start();
    }
    //客户端发送数据
    public void clientSendData(){
        sendData("客户端发送数据".getBytes(),bluetoothSocket);
    }
    //服务器端接受数据
    public void serverReadRev(){
        ReadReceiveThread sercerReadThread = new ReadReceiveThread(serverClentSocket);
        sercerReadThread.start();
    }
    //服务端发送数据
    public void serverSendData(){
        sendData("服务器端发送数据".getBytes(),serverClentSocket);
    }

    //发送数据
    public void sendData(byte[] bytStr,BluetoothSocket socket){
        try {
            OutputStream os = socket.getOutputStream();
            os.write(bytStr);
            Log.i(TAG,"发送的数据是："+new String(bytStr));

        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG,"发送数据错位");
        }

    }

    //接收数据线程
    private class ReadReceiveThread extends Thread{
        private BluetoothSocket socket;

        public ReadReceiveThread(BluetoothSocket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            byte[] buffer = new byte[1024];
            int bytes;
            Log.i(TAG,"连接成功"+socket.isConnected()+"socket"+socket);
            try {

                InputStream is = socket.getInputStream();
                bytes=is.read(buffer);
                while (true){
                    if (bytes>0){
                        byte[] buf_data=new byte[bytes];
                        for (int i = 0 ; i < bytes; i++){
                            buf_data[i]=buffer[i];
                        }
                        String str = new String(buf_data);
                        Log.i(TAG,"接收到的数据"+str);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                Log.e(TAG,"接收数据错误");
            }finally {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    //搜索蓝牙，需要进行广播接收，搜索到一个设备，就要接收一个广播
    private BroadcastReceiver mReceive = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            //寻找远程蓝牙，如果搜索到的设备跟上面过滤器中的动作一致
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                //成功搜索到远程设备，实例化对象
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                //判断远程蓝牙状态是否被绑定
                if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                    Log.i(TAG, "搜索到已经配对的设备，device name" + device.getName() + "device address " + device.getAddress());

                }else {
                    Log.i(TAG,"搜索到没有配对的设备");
                    //直接指定一个地址
                    if (device.getAddress().equals("00:20:00:76:45:39")){
                        bluetoothDevice=device;
                        Log.i(TAG,"指定配对连接的device");

                    }
                }
                //如果蓝牙装填反生了改变，那么就需要重新发送一个新的广播
            }else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)){
                //更新蓝牙设备的绑定状态
                BluetoothDevice device =  intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                //如果绑定状态==正在绑定状态
                if (device.getBondState()==BluetoothDevice.BOND_BONDED){
                    Log.i(TAG,"正在配对 device name "+device.getName()+"device address"+device.getAddress()+"device uuid"+device.getUuids());
                    //如果绑定状态==已经完成绑定状态
                }else if (device.getBondState()==BluetoothDevice.BOND_BONDED){
                    Log.i(TAG,"完成配对 device name "+device.getName()+"device address"+device.getAddress()+"device uuid"+device.getUuids());
                    //如果绑定状态==没有绑定状态
                }else if (device.getBondState()==BluetoothDevice.BOND_NONE){
                    Log.i(TAG,"取消配对 device name");
                    //蓝牙搜索结束
                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                    Log.i(TAG,"设备搜索结束！");

                }
            }
        }
    };
}
